
/*
 * @项目名称: 模板开发
 * @FilePath: /meek/src/renderer/canvas/canvaslayerrenderer.js
 * @Author: 
 * @Date: 2017-03-23T11:12:12+08:00
 * @LastEditors: yangxianghong@datatang.com
 * @LastEditTime: 2023-05-05 13:45:42
 * Copyright (c) 2018-2022
 */

/**
 * Created by zhangyong on 2017/3/20.
 */

import LayerRenderer from '../../renderer/canvas/layerrenderer'

import {Transform} from '../../data/matrix/transform'
import {ExtentUtil} from '../../geometry/support/extentutil'

export default class ImageLayerRenderer extends LayerRenderer {
  constructor (layer) {
    super(layer)

    this._image = null

    this._imageTransform = Transform.create()

    this.coordinateToCanvasPixelTransform = Transform.create()
  }

  /**
   * @inheritDoc
   */
  get image () {
    return !this._image ? null : this._image.getDomImage()
  }


  get canvas() {
    return this.layer._canvas;
  }

  /**
   * @inheritDoc
   */
  get imageTransform () { return this._imageTransform }


  /**
   *
   * @param frameState
   * @param layerState
   * @returns {boolean}
   */
  prepareFrame (frameState) {
    const pixelRatio = frameState.pixelRatio
    const size = frameState.size
    const viewState = frameState.viewState
    const viewCenter = viewState.center
    const viewResolution = viewState.resolution
    const viewRotation = viewState.rotation

    let image
    const imageLayer = this.layer
    let renderedExtent = frameState.extent

    if (!ExtentUtil.isEmpty(renderedExtent)) {
      const projection = viewState.projection

      image = imageLayer.getImageInternal(renderedExtent,
        viewResolution, pixelRatio, projection)

      // Load the image
      if (image) {
        this._image = image
      }
    }

    if (this._image) {
      image = this._image
      const imageExtent = image.extent
      const imageResolution = image.resolution
      const imagePixelRatio = image.pixelRatio
      const scale = pixelRatio * imageResolution /
        (viewResolution * imagePixelRatio)

      const transform = Transform.compose
      (this.imageTransform,
        pixelRatio * size[0] / 2,
        pixelRatio * size[1] / 2,
        scale,
        -scale,
        0,
        imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
        imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution)

      Transform.compose
      (this.coordinateToCanvasPixelTransform,
        pixelRatio * size[0] / 2 - transform[4],
        pixelRatio * size[1] / 2 - transform[5],
        pixelRatio / viewResolution,
        -pixelRatio / viewResolution,
        viewRotation
        //0,
        -viewCenter[0], -viewCenter[1])

    }

    return !!this.image
  }

  /**
   *
   * @param frameState
   * @param layerState
   * @param context
   */
  composeFrame (frameState, context) {
    this.preCompose(context, frameState)
    const image = this.canvas;
    const viewState = frameState.viewState
    const viewRotation = viewState.rotation

    if (image) {
      // clipped rendering if layer extent is set
      const extent = undefined
      const clipped = extent !== undefined &&
        !ExtentUtil.containsExtent(extent, frameState.extent) &&
         ExtentUtil.intersects(extent, frameState.extent)

      if (clipped) {
        this.clip(context, frameState, extent)
      }

      const imageLayer = this.layer
      const imageTransform = this.imageTransform



      const dx = imageTransform[4]
      const dy = imageTransform[5]
      const dw = image.width * imageTransform[0]
      const dh = image.height * imageTransform[3]

      context.save()

      const alpha = context.globalAlpha
      context.globalAlpha = imageLayer.opacity

      let x = context.canvas.width;
      let y = context.canvas.height;
      const rotation = Math.floor(viewRotation);
      if ( rotation === 0 ) {
        context.translate(0, 0);
      } else if ( rotation == 1 ) {
        context.translate((x - y) / 2, (x + y) / 2);
      } else if ( rotation == 3 ) {
        context.translate(x, y);
      } else {
        context.translate((x + y) / 2, (y - x) / 2);
      }

      context.rotate(-viewRotation)

      if (imageLayer.imageSmoothingQuality) {
        context.imageSmoothingEnabled = true
        context.imageSmoothingQuality = imageLayer.imageSmoothingQuality;
      } else {
        context.imageSmoothingEnabled = false
      }

      context.filter = `contrast(${this.layer.contrast}) brightness(${this.layer.brightness})`

      context.drawImage(image, 0, 0, +image.width, +image.height,
        Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh))

      context.globalAlpha = alpha

      context.restore()
    }

    this.postCompose(context, frameState)
  }
}
